package com.tan.lbs.entity;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import android.content.ContentValues;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.widget.Toast;

import com.tan.lbs.dao.GameRuleDAO;
import com.tan.lbs.dao.ItemDAO;
import com.tan.lbs.dao.NPCDAO;
import com.tan.lbs.dao.QuestDAO;
import com.tan.lbs.dao.impl.GameRuleDAOImpl;
import com.tan.lbs.dao.impl.ItemDAOImpl;
import com.tan.lbs.dao.impl.NPCDAOImpl;
import com.tan.lbs.dao.impl.QuestDAOImpl;
import com.tan.lbs.util.Constants;
import com.tan.lbs.util.SQLiteDatabaseHelper;

public class GameRuleManager {
	private Map<ObjectTriggerIndex, List<String>> objectTriggerIDsTable;
	private Map<String, Trigger> triggerTable;
	private static GameRuleManager manager;
	private static GameRuleDAO gameRuleDAO;
	private static Context context;
	private String gameID;

	private GameRuleManager(String gameID) {
		objectTriggerIDsTable = new HashMap<ObjectTriggerIndex, List<String>>();
		triggerTable = new HashMap<String, Trigger>();
		
		this.gameID = gameID;
	}

	public static synchronized GameRuleManager getInstance(Context updateContext,
			String gameID) {
		if (manager == null) {
			manager = new GameRuleManager(gameID);
		}
		context = updateContext;
		gameRuleDAO = new GameRuleDAOImpl(context);
		return manager;
	}

	public boolean gameRuleCheck(String gameObjectID, String gameObjectAction) {
		// cache the game rule and triggers
		if (!objectTriggerIDsTable.containsKey(gameObjectID)) {
			objectTriggerIDsTable.put(new ObjectTriggerIndex(gameObjectID,
					gameObjectAction), gameRuleDAO
					.getGameObjectAssociatedTriggerIDs(gameID, gameObjectAction,gameObjectID
							));
		}

		List<String> triggerIDs = objectTriggerIDsTable
				.get(new ObjectTriggerIndex(gameObjectID, gameObjectAction));

		Iterator<String> it = triggerIDs.iterator();
		SQLiteDatabaseHelper dbHelper = new SQLiteDatabaseHelper(context,
				Constants.LOCAL_DB_NAME);
		SQLiteDatabase db = dbHelper.getReadableDatabase();

		while (it.hasNext()) {
			String triggerID = it.next();
			if (!triggerTable.containsKey(triggerID)) {
				triggerTable.put(triggerID,
						gameRuleDAO.loadTrigger(triggerID, gameID));
			}
			Trigger trigger = triggerTable.get(triggerID);
			List<Condition> conditions = trigger.getConditions();
			int satisfiedCondition = 0;
			for (Condition condition : conditions) {
				if (condition.getConditionType().equals(
						Condition.COMPLETE_QUEST_CONDITION)) {
					Cursor cursor = db.query("quest",
							new String[] { "status" }, "questID=?",
							new String[] { condition.getParamX() }, null, null, null);
					if (cursor.moveToNext()) {
						String status = cursor.getString(cursor
								.getColumnIndex("status"));
						if (status.equals(Quest.COMPLETE_STATUS)) {
							satisfiedCondition++;
						}
					}
				} else if (condition.getConditionType().equals(
						Condition.START_QUEST_CONDITION)) {
					
						Cursor cursor = db.query("quest",
								new String[] { "status" }, "questID=?",
								new String[] { condition.getParamX() }, null, null, null);
						if (cursor.moveToNext()) {
							String status = cursor.getString(cursor
									.getColumnIndex("status"));
							if (status.equals(Quest.START_STATUS)) {
								satisfiedCondition++;
							}
						}

				} else if (condition.getConditionType().equals(
						Condition.FINISH_CHAT_CONDITION)) {
						Cursor cursor = db.query("npc",
								new String[] { "status" }, "npcID=?",
								new String[] { condition.getParamX() }, null, null, null);
						if (cursor.moveToNext()) {
							String status = cursor.getString(cursor
									.getColumnIndex("status"));
							if (status.equals(NPC.END_CHAT)) {
								satisfiedCondition++;
							}
						}
				} else if (condition.getConditionType().equals(
						Condition.GREET_CONDITION)) {
							satisfiedCondition++;
					

				} else if (condition.getConditionType().equals(
						Condition.PICK_ITEM_CONDITION)) {
					Cursor cursor = db.query("item",
							new String[] { "status" }, "itemID=?",
							new String[] { condition.getParamX() }, null, null, null);
					if (cursor.moveToNext()) {
						String status = cursor.getString(cursor
								.getColumnIndex("status"));
						if (status.equals(Item.PICKED)) {
							satisfiedCondition++;
						}
					}
				}
		
			}
			if(satisfiedCondition == conditions.size()) {
				fireTrigger(trigger);
			}
			
		}

		return true;
	}

	private void fireTrigger(Trigger trigger) {
		gameRuleDAO.updateTriggerStatus(trigger.getTriggerID(),Trigger.TRIGGER_STATUS);
		if(trigger.getActionType().equals(Trigger.BECOME_CHATTABLE_ACTION)) {
			NPCDAO npcDAO = new NPCDAOImpl(context);
			npcDAO.updateNPCStatus(trigger.getActionObjectID(), NPC.CHATTABLE);
		} else if(trigger.getActionType().equals(Trigger.BECOME_PICKABLE_ACTION)) {
			ItemDAO itemDAO = new ItemDAOImpl(context);
			itemDAO.updateItemStatus(trigger.getActionObjectID(), Item.PICKABLE);
		} else if(trigger.getActionType().equals(Trigger.COMPLETE_QUEST_ACTION)) {
			QuestDAO questDAO = new QuestDAOImpl(context);
			questDAO.updateQuestStatus(trigger.getActionObjectID(), Quest.COMPLETE_STATUS);
			int finishHighestOrder  = context.getSharedPreferences(Constants.PREFS_NAME, 0).getInt("highestAvailableQuest", 0);
			SharedPreferences.Editor editor = context.getSharedPreferences(Constants.PREFS_NAME, 0).edit();
			editor.putInt("highestAvailableQuest", finishHighestOrder+1);
			editor.commit();
			Toast.makeText(context,trigger.getTriggerText() , Toast.LENGTH_LONG).show();
			//trigger a quest complete condition
			this.gameRuleCheck(trigger.getActionObjectID(), Condition.COMPLETE_QUEST_CONDITION);
		} 
	}
}
